from tkinter import *
from tkinter.simpledialog import *
import tkinter.font as tkFont
from tool_eventer import Eventer
from tool_draw import *



nameset = set() # 名称集合
import random
def randname():
    return "__"+"".join(chr(random.randint(ord('0'), ord('9'))) for i in range(4))


class NetShow(Frame):
    LampShape = LampShape
    ConnectShape = ConnectShape
    
    
    def __init__(self, master=None):
        Frame.__init__(self, master)
        

        
        # self.canvas = Canvas(self, width=1200, height=800, background=[bglist.pop(), print("hi")][0])                  # 创建控件      background="black"
        self.canvas = Canvas(self, width=2000, height=1000, background="black")                  # 创建控件      background="black"
        # self.canvas.pack(fill=BOTH, expand=1)
        self.canvas.place(anchor=CENTER, relx=0.5, rely=0.5)
        
        
        #self.config(cursor="hand2") # 手形
        
        #G.img = PhotoImage(file="right.png", name="name1")
        #cursorid = self.canvas.create_image(100, 100, image=G.img)
        # 在鼠标旁边画点东西就算了（）……

        NetShow.LampShape.ft = tkFont.Font(family='Fixdsys', size=20, weight=tkFont.BOLD) # tk初始化后才能工作
        

        # self.netcontrol = None      # 携带的信息
        self.lampshape_dict = {}
        self.choosed = None     # 使用于：移动节点， 终止移动，设置连接起点， 绘制临时连接
        self.tempconnectshape = None    # 使用于：绘制临时连接， 删除临时连接
        self.choosed2 = None    # 使用于：绘制临时连接， 删除临时连接， 建立连接
        
        self.config_event()

        


    def config_event(self):
        self.eventer = Eventer(b_canvas=self.canvas.bind, b_tag=self.canvas.tag_bind)
        eventer = self.eventer

        # 新建/删除
        @eventer.bind("<ButtonRelease-1>", "nothing", "a_pressed")
        def _(e):
            x, y = e.x, e.y
            lampshape = NetShow.LampShape(self.canvas, x, y, randname())
            self.lampshape_dict[lampshape.rectid] = lampshape
            self.stay = lampshape
            # self.master.config(menu=self.master.menu2)                # test menu
        @eventer.bind("<ButtonRelease-1>", "nothing", "del_pressed")
        def _(event):
            l = self.canvas.find_overlapping(event.x, event.y, event.x+1, event.y+1)
            lampshape = self.findlampshape(event.x, event.y)
            if lampshape is not None:
                nameset.remove(lampshape.name)
                lampshape.del_shape()

        # 编辑文字标签
        @eventer.bind("<ButtonRelease-3>", "nothing", None) 
        def _(e):
            lampshape = self.findlampshape(e.x, e.y)
            if lampshape is not None:
                name = askstring("标签", "")
                if name:
                    if name not in nameset:
                        lampshape.set_name(name)
                        nameset.add(name)
                    else:
                        lampshape.set_name(name + randname())
                    

        # 激活型连接
        @eventer.tag_bind("<Button-1>", "lamp", "nothing", "f_pressed") # 准备连接，设置起点
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)
            if lampshape is not None:
                self.choosed = lampshape
                eventer.change_state("EN_start")
        @eventer.bind("<B1-Motion>", "EN_start", "f_pressed")   # 绘制临时连接
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)    # 不停寻找
            if lampshape is not None and lampshape is not self.choosed:
                self.choosed2 = lampshape
                self.tempconnectshape = NetShow.ConnectShape(self.canvas, self.choosed, self.choosed2, "green") # lime
                eventer.change_state("EN_findone")
        @eventer.bind("<B1-Motion>", "EN_findone", "f_pressed")
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)    # 不停寻找
            if lampshape is None or lampshape is self.choosed:
                # 删除临时连接
                self.tempconnectshape.del_shape()
                self.tempconnectshape = None
                self.choosed2 = None
                eventer.change_state("EN_start")
        @eventer.bind("<ButtonRelease-1>", "EN_start", "f_pressed")
        def _(event):
            eventer.change_state("nothing")
        @eventer.bind("<ButtonRelease-1>", "EN_findone", "f_pressed") # 确定添加连接 
        def _(event):
            if self.choosed2 in (connectshape.endlamp for connectshape in self.choosed.connectto):
                pass
            else:
                self.choosed.connectto.append(self.tempconnectshape)
                self.choosed2.connectfrom.append(self.tempconnectshape)
                self.tempconnectshape = None
            self.choosed = None
            self.choosed2 = None
            eventer.change_state("nothing")
        
        # 抑制型连接
        @eventer.tag_bind("<Button-1>", "lamp", "nothing", "g_pressed") # 准备连接，设置起点
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)
            if lampshape is not None:
                self.choosed = lampshape
                eventer.change_state("EN_start")
        @eventer.bind("<B1-Motion>", "EN_start", "g_pressed")   # 绘制临时连接
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)    # 不停寻找
            if lampshape is not None and lampshape is not self.choosed:
                self.choosed2 = lampshape
                self.tempconnectshape = NetShow.ConnectShape(self.canvas, self.choosed, self.choosed2, "firebrick") # red
                eventer.change_state("EN_findone")
        @eventer.bind("<B1-Motion>", "EN_findone", "g_pressed")
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)    # 不停寻找
            if lampshape is None or lampshape is self.choosed:
                # 删除临时连接
                self.tempconnectshape.del_shape()
                self.tempconnectshape = None
                self.choosed2 = None
                eventer.change_state("EN_start")
        @eventer.bind("<ButtonRelease-1>", "EN_start", "g_pressed")
        def _(event):
            eventer.change_state("nothing")
        @eventer.bind("<ButtonRelease-1>", "EN_findone", "g_pressed") # 确定添加连接 
        def _(event):
            if self.choosed2 in (connectshape.endlamp for connectshape in self.choosed.connectto):
                pass
            else:
                self.choosed.connectto.append(self.tempconnectshape)
                self.choosed2.connectfrom.append(self.tempconnectshape)
                self.tempconnectshape = None
            self.choosed = None
            self.choosed2 = None
            eventer.change_state("nothing")

        # 删除连接
        @eventer.tag_bind("<Button-1>", "lamp", "nothing", "v_pressed")
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)
            if lampshape is not None:
                self.choosed = lampshape
                eventer.change_state("del_start")
        @eventer.bind("<B1-Motion>", "del_start", "v_pressed")   # 绘制临时连接
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)    # 不停寻找
            if lampshape is not None and lampshape is not self.choosed:
                self.choosed2 = lampshape
                eventer.change_state("del_findone")
        @eventer.bind("<B1-Motion>", "del_findone", "v_pressed")
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)    # 不停寻找
            if lampshape is None or lampshape is self.choosed:
                self.choosed2 = None
                eventer.change_state("del_start")
        @eventer.bind("<ButtonRelease-1>", "del_start", "v_pressed")
        def _(event):
            eventer.change_state("nothing")
        @eventer.bind("<ButtonRelease-1>", "del_findone", "v_pressed") # 确定添加连接 
        def _(event):
            if self.choosed2 in (connectshape.endlamp for connectshape in self.choosed.connectto):
                for connectshape in self.choosed.connectto:
                    if (connectshape.endx, connectshape.endy) == (self.choosed2.x, self.choosed2.y):
                        print("del ok")
                        connectshape.del_shape()
                        break
                else:
                    print("not ok")
                # 如果并没有break（比如空for），结果就是错的
                self.choosed.connectto.remove(connectshape)
                self.choosed2.connectfrom.remove(connectshape)
            else:
                pass
            self.choosed = None
            self.choosed2 = None
            eventer.change_state("nothing")

        # 移动节点
        @eventer.tag_bind("<Button-1>", "lamp", "nothing")  
        def _(event):
            lampshape = self.findlampshape(event.x, event.y)
            if lampshape is not None:
                self.choosed = lampshape
                eventer.change_state("move")
        @eventer.bind("<B1-Motion>", "move")
        def _(event):
            x, y = event.x, event.y
            self.choosed.move(x, y)
            for connect in self.choosed.connectto:  # 改变连接
                connect.move_start(x, y)
            for connect in self.choosed.connectfrom:
                connect.move_end(x, y)
        @eventer.bind("<ButtonRelease-1>", "move")
        def _(event):
            self.choosed = None
            eventer.change_state("nothing")


    def findlampshape(self, x, y):   # 工具函数
        l = self.canvas.find_overlapping(x-2, y-2, x+2, y+2)
        for id in reversed(l):
            lampshape = self.lampshape_dict.get(id, None)
            if lampshape is not None:
                return lampshape

    def output(self):   # 输出网络关系为python对象
        lamps = []
        connects = {}
        for lampshape in self.lampshape_dict.values():
            lamps.append((lampshape.name, lampshape.x, lampshape.y))
            connects[lampshape.name] = [connect.endlamp.name for connect in lampshape.connectto]
        return (lamps, connects)

    def input(self, info):
        lamps, connects = info 
        d = {}
        for name, x, y in lamps:
            if name.startswith("__"):
                lampshape = NetShow.LampShape(self.canvas, x, y, "")
            elif "__" in name:
                lampshape = NetShow.LampShape(self.canvas, x, y, name.split("__")[0])
            else:
                lampshape = NetShow.LampShape(self.canvas, x, y, name)
            self.lampshape_dict[lampshape.rectid] = lampshape
            d[name] = lampshape
        for source, targets in connects.items():
            lamp1 = d[source]
            for target in targets:
                lamp2 = d[target]
                connectshape = NetShow.ConnectShape(self.canvas, lamp1, lamp2, color="green")
                lamp1.connectto.append(connectshape)
                lamp2.connectfrom.append(connectshape)


class Page1:
    def __init__(self, mainwindow):
        self.mainwindow = mainwindow
        self.netshow = NetShow()

    def start(self):
        self.netshow.pack(fill=BOTH, expand=1)

    def end(self):
        self.netshow.pack_forget() # 鼠标事件随之消失  # 键盘事件原则上应该解绑
            

 